package com.example.chatbackend.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Minimal Aliyun POP client to call NLS CreateToken without the official SDK.
 */
public class AliyunPopTokenClient {
    public static class TokenResult {
        public final String token;
        public final long expireTime;

        public TokenResult(String token, long expireTime) {
            this.token = token;
            this.expireTime = expireTime;
        }
    }

    public static TokenResult createToken(String accessKeyId, String accessKeySecret) throws Exception {
        Map<String, String> params = new HashMap<>();
        params.put("AccessKeyId", accessKeyId);
        params.put("Action", "CreateToken");
        params.put("Version", "2019-02-28");
        params.put("Format", "JSON");
        params.put("RegionId", "cn-shanghai");
        params.put("SignatureMethod", "HMAC-SHA1");
        params.put("SignatureVersion", "1.0");
        params.put("SignatureNonce", uuidNonce());
        params.put("Timestamp", iso8601Utc());

        String signature = sign("POST", params, accessKeySecret + "&");
        params.put("Signature", signature);

        byte[] body = buildFormBody(params).getBytes(StandardCharsets.UTF_8);
        URL url = new URL("https://nls-meta.cn-shanghai.aliyuncs.com/");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setConnectTimeout(8000);
        conn.setReadTimeout(8000);
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.getOutputStream().write(body);
        int code = conn.getResponseCode();
        Scanner s = new Scanner(code >= 200 && code < 300 ? conn.getInputStream() : conn.getErrorStream(), StandardCharsets.UTF_8.name()).useDelimiter("\\A");
        String resp = s.hasNext() ? s.next() : "";
        s.close();
        if (code < 200 || code >= 300) {
            throw new RuntimeException("CreateToken failed: HTTP " + code + ", body=" + resp);
        }
        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(resp);
        JsonNode token = root.path("Token");
        String id = token.path("Id").asText(null);
        long expire = token.path("ExpireTime").asLong(-1);
        if (id == null || id.isEmpty() || expire <= 0) {
            throw new RuntimeException("CreateToken response parse failed: " + resp);
        }
        return new TokenResult(id, expire);
    }

    private static String iso8601Utc() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        return sdf.format(new Date());
    }

    private static String uuidNonce() {
        return UUID.randomUUID().toString();
    }

    private static String sign(String method, Map<String, String> params, String signingKey) throws Exception {
        SortedMap<String, String> sorted = new TreeMap<>(params);
        StringBuilder canonicalized = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> e : sorted.entrySet()) {
            if (!first) canonicalized.append("&");
            first = false;
            canonicalized.append(percentEncode(e.getKey())).append("=").append(percentEncode(e.getValue()));
        }
        String stringToSign = method.toUpperCase(Locale.ROOT)
                + "&" + percentEncode("/")
                + "&" + percentEncode(canonicalized.toString());
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(new SecretKeySpec(signingKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
        byte[] raw = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(raw);
    }

    private static String percentEncode(String s) {
        try {
            String encoded = URLEncoder.encode(s, "UTF-8");
            // POP encoding adjustments
            encoded = encoded.replace("+", "%20")
                    .replace("*", "%2A")
                    .replace("%7E", "~");
            return encoded;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String buildFormBody(Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> e : params.entrySet()) {
            if (!first) sb.append('&');
            first = false;
            sb.append(e.getKey()).append('=').append(percentEncode(e.getValue()));
        }
        return sb.toString();
    }

    // removed ad-hoc JSON parsing helpers; using Jackson instead
}


